package org.jeecg.modules.demo3.fly.TCP;


import lombok.Data;
import org.apache.commons.collections.bag.SynchronizedSortedBag;
import org.apache.poi.hssf.record.PageBreakRecord;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.util.YouBianCodeUtil;
import org.jeecg.modules.demo3.fly.controller.qun.QunController;
import org.jeecg.modules.demo3.fly.entity.AxhkYwAgrplane;
import org.jeecg.modules.demo3.fly.entity.tcp.Clents;
import org.jeecg.modules.demo3.fly.entity.tcp.DistributionDataBean;
import org.jeecg.modules.demo3.fly.mapper.AxhkYwAgrplaneMapper;
import org.jeecg.modules.demo3.fly.utils.Base_Conversion;
import org.jeecg.modules.demo3.fly.utils.BeanContext;
import org.jeecg.modules.demo3.fly.utils.DateShift;
import org.jeecg.modules.demo3.fly.utils.FileInsert;

import javax.annotation.Resource;
import javax.swing.plaf.synth.SynthOptionPaneUI;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;

/**
 * @author wjn
 * @version V1.0
 * @date 2021/2/26 11:35
 * @Copyright © 2021/2/26 深圳卓翼航空无人机有限公司
 */
@Data
public class ServerConfig implements Runnable {
    private Clents clents;//客户端对象
    private List<Clents> sockets; //所有客户端 socket集合
    DateShift dateShift = new DateShift(); //数据解析类
    private boolean connected = true;
    private int serial_number; //序列号
    private boolean statrs = false;
    int i = 0;
    FileInsert fileInsert = new FileInsert();    //数据储存类
    @Resource
    private AxhkYwAgrplaneMapper axhkYwAgrplaneMapper = BeanContext.getBean(AxhkYwAgrplaneMapper.class);
    public ServerConfig(Clents clents, List<Clents> sockets) {
        this.clents = clents;
        this.sockets = sockets;
    }

    @Override
    public void run() {
        try {
            clents.getSocket().setKeepAlive(true);
            clents.getSocket().setSoTimeout(20 * 1000); //过期时间-设置
            int length = 0; //数据长度
            try {
                clents.getSocket().sendUrgentData(0xFF);
                while (connected) {
                    try {
                        byte[] byt = new byte[1024];
                        InputStream ips = clents.getIs();
                        length = ips.read(byt); //length = 104
                        if (length != -1) { //客户端发送数据不为空
                            if (length > 10) { // 当数据长度大于4 说明客户端发的不是心跳包
                                DistributionDataBean distributionDataBean = dateShift.issue_Agreement(byt, length); // 数据解析
                                if (null != distributionDataBean) { //说明数据解析正确
                                    serial_number = distributionDataBean.getSerial_number();
                                    clents.setNumber(serial_number);
                                    clents.setSta(1); //4g客户端
                                    if (statrs == false) {
                                        // 客户端socket 有数据进入此时状态为在线  state设置为1
                                        AxhkYwAgrplane axhkYwAgrplane = axhkYwAgrplaneMapper.getAllAxhkYwAgrplane(serial_number);
                                        if (null != axhkYwAgrplane) {
                                            int state = 1;
                                            i = axhkYwAgrplaneMapper.getUpdateState(serial_number, state);//修改在线状态  1
                                        }
                                        statrs = true;
                                    }
                                    if (i > 0) {
                                        fileInsert.WriterReader(distributionDataBean, serial_number, clents); // 调用输入流 将数据对象保存在本地
                                        //调用转发数据 方法
                                        sendToClient(byt);
                                    }
                                } else { //数据解析不正确 是手机APP用户指令 指令直接转发
                                        /*String bb = byteToHex(byt);
                                        System.out.println("指令bb："+bb);*/
                                    sendToClient(byt);
                                }
                            } else { //客户端发送的是心跳包
                                clents.setSta(0); // APP客户端
                                Integer number = Base_Conversion.byte3intLittleEndian(byt); //调用方法 将byt转成int
                                clents.setNumber(number); // 客户端添加标识
                                   /* String aa = byteToHex(byt);
                                    System.out.println("指令aa："+aa);*/
                                sendToClient(byt);
                            }
                        } else { // 客户端发送数据为空
                            connected = false;
                            bye(clents);
                        }
                    } catch (SocketTimeoutException e) {
                        System.out.println("异常 socket连接超时");
                        connected = false;
                        bye(clents);
                    }
                    Thread.sleep(10); //线程休眠10毫秒
                }
            } catch (Exception e) {
                System.out.println("异常 客户端自己断开！");
                connected = false;
                bye(clents);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //转发消息
    private void sendToClient(byte[] bytes) throws IOException {
        if (!sockets.isEmpty()) {
            for (Clents clent : sockets) {
                if ((clents.getNumber() == clent.getNumber() && clents.getNumber() != 0) && clent != clents) {
                    while (true) {
                        OutputStream outputStream = clent.getOs();
                        outputStream.write(bytes);
                        outputStream.flush();
                        break;
                    }
                }
            }
        }
    }

    //关闭资源
    public void bye(Clents clents) throws IOException {
        if (clents.getNumber() == 0) {
            System.out.println("未带有序列号！");
            Clents clents1 = null;
            for (int j = 0; j < sockets.size(); j++) {
                clents1 = sockets.get(j);
                if (clents1 == clents) {
                    clents1.getIs().close();
                    clents1.getOs().close();
                    clents1.getSocket().close();
                    sockets.remove(clents1);
                }
                System.out.println(sockets.get(j));
            }
        } else {
            System.out.println("带有序列号！");
            System.out.println("未删除前的集合长度:" + sockets.size());
            System.out.println("断开的客户端标志：" + clents.getSta());
            Clents clents1 = null;
            for (int j = 0; j < sockets.size(); j++) {
                clents1 = sockets.get(j);
                if (clents1 == clents && clents1.getSta() == clents.getSta()) {
                    clents1.getIs().close();
                    clents1.getOs().close();
                    clents1.getSocket().close();
                    // 删除客户端后 将状态改为 未在线
                    int serialNumber = clents.getNumber();
                    if (clents1.getSta() == 1) { //4g用户
                        int state = 0;
                        AxhkYwAgrplane axhkYwAgrplane = axhkYwAgrplaneMapper.getAllAxhkYwAgrplane(serialNumber);
                        if (null != axhkYwAgrplane && clents1.getSta() == 1) {
                            int a = axhkYwAgrplaneMapper.getUpdateState(serialNumber, state); //修改在线状态  0
                            if (a > 0) {
                                i = 0;
                                statrs = false;
                            }
                        }
                    } else { // 手机APP用户
                        System.out.println("1");
                        int astate = 0;
                        int connStatus = 1;
                        axhkYwAgrplaneMapper.getUpdateAstate(serialNumber, astate,connStatus);
                    }
                    sockets.remove(clents1); //集合删除
                }
            }
            System.out.println("删除后的集合长度:" + sockets.size());
        }
    }

    //十进制转换成十六进制  测试
    public static String byteToHex(byte[] bytes) {
        StringBuffer stringBuffer = new StringBuffer();
        for (int n = 0; n < bytes.length; n++) {
            String hex = Integer.toHexString(bytes[n] & 0xFF);
            if (hex.length() < 2) {
                stringBuffer.append(0);
            }
            stringBuffer.append(hex);
        }
        return stringBuffer.toString();
    }

}
